package com.arui.rpc.transport.socket.server;

import com.arui.rpc.handler.RequestHandler;
import com.arui.rpc.hook.ShutdownHook;
import com.arui.rpc.provider.ServiceProviderImpl;
import com.arui.rpc.registry.NacosServiceRegistry;
import com.arui.rpc.transport.AbstractRpcServer;
import com.arui.rpc.enumeration.RpcError;
import com.arui.rpc.exception.RpcException;
import com.arui.rpc.serializer.CommonSerializer;
import com.arui.rpc.factory.ThreadPoolFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * @Auther: zhanyurui
 * @Date: 2021-08-08 18:37
 * @Description: 远程方法调用的提供者（服务端）
 */
public class SocketServer  extends AbstractRpcServer {
    private final ExecutorService threadPool;
    private final CommonSerializer serializer;
    private final RequestHandler requestHandler = new RequestHandler();
    public SocketServer(String host, int port) {
        this(host, port, DEFAULT_SERIALIZER);
    }
    public SocketServer(String host, int port, Integer serializer) {
        this.host = host;
        this.port = port;
        threadPool = ThreadPoolFactory.createDefaultThreadPool("socket-rpc-server");
        this.serviceRegistry = new NacosServiceRegistry();
        this.serviceProvider = new ServiceProviderImpl();
        this.serializer = CommonSerializer.getByCode(serializer);
        scanServices();
    }
    public void start(){
        try (ServerSocket serverSocket = new ServerSocket()) {
            serverSocket.bind(new InetSocketAddress(host,port));
            logger.info("服务器正在启动");
            Socket socket;
            ShutdownHook.getShutdownHook().addClearAllHook();
            while((socket = serverSocket.accept())!=null){
                logger.info("消费者连接：{}{}"+socket.getInetAddress(),socket.getPort());
                threadPool.execute(new SocketRequestHandlerThread(socket,requestHandler,serviceRegistry,serializer));
            }
        } catch (IOException e) {
            logger.error("连接时有错误发生：", e);
        }
    }

}
